package com.zfl.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;



/**
 * Redis配置类：配置RedisTemplate，优化序列化方式
 */
@Configuration
public class RedisConfig {

    /**
     * 自定义RedisTemplate，解决默认序列化乱码问题
     * 支持键为String，值为任意对象（通过JSON序列化）
     */
//    @Bean
//    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//        RedisTemplate<String, Object> template = new RedisTemplate<>();
//        // 设置连接工厂
//        template.setConnectionFactory(factory);
//
//        // 1. 配置键（key）的序列化器：StringRedisSerializer（避免键乱码）
//        StringRedisSerializer stringSerializer = new StringRedisSerializer();
//        template.setKeySerializer(stringSerializer);
//        template.setHashKeySerializer(stringSerializer); // Hash结构的键也用String序列化
//
//        // 2. 配置值（value）的序列化器：GenericJackson2JsonRedisSerializer（JSON格式，支持对象序列化）
//        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
//        template.setValueSerializer(jsonSerializer);
//        template.setHashValueSerializer(jsonSerializer); // Hash结构的值也用JSON序列化
//
//        // 初始化参数
//        template.afterPropertiesSet();
//        return template;
//    }

    /**
     * 全局初始化 FastJSON 1.x 序列化特性
     * 解决日期格式、空值处理、循环引用等问题
     */
    static {
        // 日期格式化（统一转为 "yyyy-MM-dd HH:mm:ss" 格式）
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteDateUseDateFormat.getMask();
        // 空字符串字段序列化为 ""（避免默认序列化后为 null）
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullStringAsEmpty.getMask();
        // 空集合字段序列化为 []（避免默认序列化后为 null）
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullListAsEmpty.getMask();
        // 禁用循环引用检测（避免序列化时出现 "$ref" 引用标记）
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
        // 数值字段 null 时序列化为 0（可选，根据业务需求开启）
        // JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullNumberAsZero.getMask();
    }

    /**
     * 自定义 RedisTemplate，使用 FastJSON 1.x 序列化值，String 序列化键
     * 适配缓存分页查询结果、多条件查询缓存等场景
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 1. 实例化 RedisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 2. 配置键（key）序列化器：使用 String 序列化（保持 key 可读性）
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer); // hash 类型的 key 也用 String 序列化

        // 3. 配置值（value）序列化器：使用 FastJSON 1.x 序列化
        FastJsonRedisSerializer<Object> fastJsonSerializer = new FastJsonRedisSerializer<>(Object.class);
        redisTemplate.setValueSerializer(fastJsonSerializer);
        redisTemplate.setHashValueSerializer(fastJsonSerializer); // hash 类型的 value 也用 FastJSON 序列化

        // 4. 初始化 RedisTemplate（必须调用，否则序列化配置不生效）
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    /**
     * 可选：单独配置StringRedisTemplate（专门处理String类型的键值对，性能略高）
     * 如果你需要频繁操作String类型数据（如缓存简单的字符串），可以注入这个Bean
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        return template;
    }
}
